package ParaSet

import (
	"encoding/json"
	"fmt"
	"github.com/bitly/go-simplejson"
	"reflect"
)

const (
	MIXDEV_LEN = 10
)

//https://mholt.github.io/json-to-go/ 网站生成
type ParaSet struct {
	AfterOpen         int           `json:"AfterOpen"`
	CoolTemp          float64       `json:"CoolTemp"`
	CurtainLimit      int           `json:"CurtainLimit"`
	CurtainStart      int           `json:"CurtainStart"`
	DownPeriod        int           `json:"DownPeriod"`
	FanPeriod         int           `json:"FanPeriod"`
	FanStart          int           `json:"FanStart"`
	FirstLevel        int           `json:"FirstLevel"`
	HappyInterval     float64       `json:"HappyInterval"`
	IvFanStart        int           `json:"IvFanStart"`
	MinimalLevel      int           `json:"MinimalLevel"`
	MixDev            []interface{} `json:"MixDev"`
	MixEndTime        int           `json:"MixEndTime"`
	MixFanStart       int           `json:"MixFanStart"`
	MixStartLevel     int           `json:"MixStartLevel"`
	MixStartTime      int           `json:"MixStartTime"`
	OpenDelay         int           `json:"OpenDelay"`
	OpenTime          int           `json:"OpenTime"`
	OutsideTemp       float64       `json:"OutsideTemp"`
	PrecisionVenStart int           `json:"PrecisionVenStart"`
	QuickDelay        int           `json:"QuickDelay"`
	QuitTemp          float64       `json:"QuitTemp"`
	SimpleDelayPeriod int           `json:"SimpleDelayPeriod"`
	SimpleFanPeriod   int           `json:"SimpleFanPeriod"`
	SimpleFanStart    int           `json:"SimpleFanStart"`
	SprayerStart      int           `json:"SprayerStart"`
	TargetTemp        float64       `json:"TargetTemp"`
	TargetTempMode    int           `json:"TargetTempMode"`
	TimerStart        int           `json:"TimerStart"`
	UpPeriod          int           `json:"UpPeriod"`
	WcurtainPeriod    int           `json:"WcurtainPeriod"`
	WcurtainStart     int           `json:"WcurtainStart"`
}

//用json为struct赋值
func (ps *ParaSet) SetValue(js *simplejson.Json) {
	b, _ := js.Encode()
	json.Unmarshal(b, ps)
}

//用反射的方式将结构体字节化按照以下规则
// int直接解析为2byts（最低两位）
// float 先*10 取整再解析为2byts
func (ps *ParaSet) Tobytes() []byte {
	reb := []byte{}
	refps := reflect.ValueOf(ps).Elem()     //获取成员对象
	for i := 0; i < refps.NumField(); i++ { //i代表字段数
		f := refps.Field(i) //字段
		switch f.Kind() {
		//如果是int将其取2个字节加入
		case reflect.Int:
			u16 := uint16(f.Int())
			reb = append(reb, uin16_to_bytes(u16)...)
		case reflect.Slice:
			for i := 0; i < f.Len(); i++ {
				fmt.Println(f.Index(i))
				u16 := uint16(f.Index(i).Interface().(float64))
				//fmt.Println(u16)
				reb = append(reb, uin16_to_bytes(u16)...)
			}
			//为了让这个数组固定一个长度MIXDEV_LEN
			if f.Len() < MIXDEV_LEN {
				for i := 0; i < MIXDEV_LEN-f.Len(); i++ {
					reb = append(reb, []byte{0x00, 0x00}...) //补0
				}
			}
		case reflect.Float64:
			u16 := uint16(f.Float() * 10)
			reb = append(reb, uin16_to_bytes(u16)...)
		}
	}
	return reb
}

//因为是要给单片机用，以小端的方式编码
func uin16_to_bytes(u16 uint16) []byte {
	b := []byte{}
	//小端，低尾端，先低位后高位
	b = append(b, byte(u16))
	b = append(b, byte(u16>>8))
	return b
}
